from flask import current_app
from flask import g
from flask import render_template
from flask import request, jsonify

from info import db
from info.models import News, Comment, CommentLike
from info.modules.news import news_blu
from info.utils.common import login_user_info
from info.utils.response_code import RET

###点赞
"""
1.判断用户是否登陆
2.获取参数
3.校验非空
4.校验操作方式
5.获取评论对象
6.添加/减少点赞列表
7.返回数据
"""


@news_blu.route('/comment_like', methods=['POST'])
@login_user_info
def comment_like():
    # 1.判断用户是否登陆
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg='用户未登录')
    # 2.获取参数
    comment_id = request.json.get('comment_id')
    news_id = request.json.get('news_id')
    action = request.json.get('action')
    # 3.校验非空
    if not all([comment_id, news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数缺少')
    # 4.校验操作方式
    if action not in ['add', 'remove']:
        return jsonify(errno=RET.PARAMERR, errmsg='参数不不合法')
    # 5.获取评论对象
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询失败')
    if not comment:
        return jsonify(errno=RET.NODATA, errmsg='评论不存在')
    # 6.添加/减少点赞列表
    # 判断该用户是否已经点过赞
    try:
        comment_like = CommentLike.query.filter(CommentLike.comment_id == comment_id,
                                                CommentLike.user_id == g.user.id).first()
        if not comment_like and action == 'add':
            commentlike = CommentLike()
            commentlike.comment_id = comment_id
            commentlike.user_id = g.user.id
            db.session.add(commentlike)
            comment.like_count += 1
            db.session.commit()
        elif comment_like and action == 'remove':
            db.session.delete(comment_like)
            comment.like_count -= 1
            db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        # 7.返回数据
    return jsonify(errno=RET.OK, errmsg='成功')


###评论
"""
1.判断用户是否登陆
2.获取参数
3.非空校验
5.获取到新闻对象
6.创建评论对象,添加属性
7.添加/减少
8.返回数据
"""


@news_blu.route('/news_comment', methods=['POST'])
@login_user_info
def news_comment():
    # 1.判断用户是否登陆
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg='用户未登录')
    # 2.获取参数
    news_id = request.json.get('news_id')
    content = request.json.get('comment')
    parent_id = request.json.get('parent_id')
    # 3.非空校验
    if not all([news_id, content]):
        return jsonify(errno=RET.PARAMERR, errmsg='缺少参数')
    # 5.获取到新闻对象
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='操作异常')
    if not news:
        return jsonify(errno=RET.NODATA, errmsg='新闻不存在')
    # 6.创建评论对象,添加属性
    comment = Comment()
    comment.user_id = g.user.id
    comment.content = content
    comment.news_id = news_id
    if parent_id:
        comment.parent_id = parent_id
    # 7.添加
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
    # 8.返回数据
    return jsonify(errno=RET.OK, errmsg='成功', data=comment.to_dict())


##新闻收藏
"""
0.判断用户是否登陆
1.获取参数
2.校验非空
3.判断操作方式
4.获取当前新闻id
5.判断添加/取消
6.返回响应
"""


@news_blu.route('/news_collect', methods=['POST'])
@login_user_info
def news_collect():
    # 0.判断用户是否登陆
    if not g.user:
        return jsonify(errno=RET.NODATA, errmsg='用户未登录')
    # 1.获取参数
    news_id = request.json.get('news_id'),
    action = request.json.get('action')
    # 2.校验非空
    if not all(['news_id', 'action']):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
    # 3.判断操作方式
    if not action in ['collect', 'cancel_collect']:
        return jsonify(errno=RET.PARAMERR, errmsg='类型错误')
    # 4.获取当前新闻对象,并判断该对象是否存在
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取失败')
    if not news:
        return jsonify(errno=RET.NODATA, errmsg='新闻不存在')
    # 5.判断添加/取消
    try:
        if action == 'collect':
            g.user.collection_news.append(news)
        else:
            g.user.collection_news.remove(news)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='操作失败')
    # 6.返回响应
    return jsonify(errno=RET.OK, errmsg='操作成功')


# 新闻详情页
@news_blu.route('/<int:news_id>')
@login_user_info
def news_detail(news_id):
    """""
    1.获取参数
    2.通过新闻id,获取新闻内容
    3.判断是否有该条新闻
    4.返回
    """
    # 1.获取参数
    # 2.通过新闻id,获取新闻内容
    news = News.query.get(news_id)
    # 3.判断是否有该条新闻
    if not news:
        return jsonify(errno=RET.NODATA, errmsg='该新闻不存在')

    user_info = g.user

    # 获取排行榜
    try:
        news_clicks = News.query.order_by(News.clicks.desc()).limit(10)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据获取失败')
    clicks_list = [news.to_dict() for news in news_clicks]

    # 获取当前新闻的评论列表
    comments = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()

    """"""""""""
    # 根据当前用户的id 在点赞列表中 查询到该用户点赞所有评论id
    user_comment_like = CommentLike.query.filter(CommentLike.user_id == g.user.id).all()

    # 获取用户点赞对象中的评论id列表
    user_comment_like_ids = [user_comment.comment_id for user_comment in user_comment_like]

    # 获取当前新闻下所有的评论id列表
    comments_ids = [comment.id for comment in comments]

    # 这个评论id列表中,哪些被点赞了 --> 获取被点过赞的评论id列表
    this_comment_like_ids = []
    for user_comment_like_id in user_comment_like_ids:
        if user_comment_like_id in comments_ids:
            this_comment_like_ids.append(user_comment_like_id)

    comments_list = []
    for comment in comments:
        comment_dict = comment.to_dict()
        comment_dict['isLike'] = False
        if comment.id in this_comment_like_ids:
            comment_dict['isLike'] = True
        comments_list.append(comment_dict)

    data = {
        'news': news,
        'user_info': user_info,
        'clicks_list': clicks_list,
        'comments': comments_list
    }
    # 4.返回
    return render_template('news/detail.html', data=data)
